package hashTable

import "container/list"

// 设置一个较大的经验参数
var base = 1000

// entry用于存储实际的key/value值,可以换成其他需要存储的类型
type entry struct {
	key, value int
}

// HashMap底层是一个切片,切片每个元素是一个链表的头节点
type MyHashMap struct {
	// list.List是内置的链表类型
	data []list.List
}

func Constructor() MyHashMap {
	return MyHashMap{data: make([]list.List, base)}
}

// 计算key的hash值
func (m *MyHashMap) Hash(key int) int {
	return key % base
}

func (m *MyHashMap) Put(key, value int) {
	i := m.Hash(key)
	// 遍历i位置的链表: for e := list.List.Front(); e != nil; e = e.Next() {}
	// 其中e为节点类型的指针,所以e.Value会修改节点值
	// 获取entry: et := e.Value.(entry)
	for e := m.data[i].Front(); e != nil; e = e.Next() {
		if et := e.Value.(entry); et.key == key {
			e.Value = entry{key, value}
			return
		}
	}
	m.data[i].PushBack(entry{key, value})
}

func (m *MyHashMap) Get(key int) int {
	i := m.Hash(key)
	for e := m.data[i].Front(); e != nil; e = e.Next() {
		if et := e.Value.(entry); et.key == key {
			return et.value
		}
	}
	return -1
}

func (m *MyHashMap) Remove(key int) {
	i := m.Hash(key)
	for e := m.data[i].Front(); e != nil; e = e.Next() {
		if et := e.Value.(entry); et.key == key {
			m.data[i].Remove(e)
			return
		}
	}
}

/**
 * Your MyHashMap object will be instantiated and called as such:
 * obj := Constructor();
 * obj.Put(key,value);
 * param_2 := obj.Get(key);
 * obj.Remove(key);
 */
